#![allow(non_snake_case)]
use crate::{
    components::{json_val_to_string, CommonPage},
    report::Report,
};
use leptos::prelude::*;
use serde_json::Value;
use shq_common::prelude::{
    report::{AuthFilter, AuthFilterType},
    ActionKind, ColumnCells, ContextMenuItem, TriggerMode, WhereCause,
};
pub struct SubHeaderSignal {
    pub context_action_index: RwSignal<Option<usize>>,
    pub maximize_sub_window: RwSignal<bool>,
}
#[component]
pub fn SubReport(
    menu_id: u32,
    header_cells: Memo<ColumnCells>,
    param_vals: RwSignal<Vec<(String, String)>>,
    cur_col_index: MaybeProp<usize>,
    sel_col: ReadSignal<Option<(String, bool)>>,
    menu_item: Memo<Option<ContextMenuItem>>,
    sub_header_signal: SubHeaderSignal,
    row_data: Memo<Option<Value>>,
    sub_style: MaybeProp<String>,
) -> impl IntoView {
    let sub_header_signal = StoredValue::new(sub_header_signal);
    provide_context(sub_header_signal);
    let title = MaybeProp::derive(move || {
        let t = menu_item.with(|mi| {
            let mi = mi.as_ref().expect("没有找到菜单项");
            let sub_title = if mi.trigger.mode == TriggerMode::Col {
                let col_name = sel_col.with(|cci| cci.as_ref().map(|(name, _)| {
                    name.clone()
                })).expect("没有选中列");
                header_cells.with_untracked(|hc| {
                    let col=hc.get_leaf_cell_by_name(&col_name).expect("没有找到对应的列");
                    col.title.clone()
                })
            } else {
                header_cells.with_untracked(|hc| {
                    row_data
                        .with(|rd| rd.as_ref().map(|rd| get_context_sub_title(mi, rd, hc)))
                        .flatten()
                })
            };
            if let Some(sub_title) = sub_title {
                format!("{} - {}", mi.caption, sub_title)
            } else {
                mi.caption.clone()
            }
        });
        Some(t)
    });
    let action_view = move || {
        let menu_item = menu_item.with(|mi| mi.clone()).expect("没有找到菜单项");
        let row_data = StoredValue::new(row_data.with(|rd| rd.clone()));
        let acts = menu_item.context_actions.clone();
        let col_name = Memo::new(move |_| {
            header_cells
                .with_untracked(|hc| {
                    let c = hc.get_show_leaf_cell_by_idx(cur_col_index.get().unwrap_or(0));
                    c.map(|c| c.name.clone())
                })
                .expect("没有找到列")
        });
        let wc = StoredValue::new(col_name.with(|n| {
            let w = menu_item.trigger.col_name_where_map.get(n);
            w.and_then(|w| {
                if w.as_str() == "" {
                    None
                } else {
                    Some(w.clone())
                }
            })
        }));
        let act_views = acts
            .into_iter()
            .map(|act| {
                let extra_where = MaybeProp::derive(move || {
                    let has_lp = param_vals.with(|ps| ps.iter().any(|(k, _v)| k == "empl_level"));
                    let empl_where = if !has_lp {
                        let (level, id) = header_cells.with(|hcs| {
                            let idx1 = hcs.get_position("empl_level");
                            let idx2 = hcs.get_position("empl_id");
                            if idx1.is_some() && idx2.is_some() {
                                let idx1 = idx1.unwrap();
                                let idx2 = idx2.unwrap();
                                let (level,id)=row_data.with_value(|row| {
                                    row.as_ref().map(|r|r.as_array().map(|obj|(obj.get(idx1).cloned(),obj.get(idx2).cloned()))).expect("没有选中行").expect("选中行不是数组")
                                });
                                (level, id)
                            } else {
                                (None, None)
                            }
                        });
                        if id.is_some() && level.is_some() && act.auth_filter.is_some() {
                            let level = level.unwrap();
                            let id = id.unwrap();
                            let auth_filter = act.auth_filter.as_ref().unwrap();
                            Some(get_empl_where_cause(&level,auth_filter, &id))
                        } else {
                            None
                        }
                    } else {
                        None
                    };
                    let wc_str = wc.get_value()
                        .map(|wc| {
                            if let Some(ew) = empl_where.as_ref() {
                                Some(format!("{wc} and {ew}"))
                            } else {
                                Some(wc.to_owned())
                            }
                        })
                        .unwrap_or(empl_where);
                    wc_str
                });
                let act_view = match act.kind {
                    ActionKind::Report => {
                        let col_name = col_name.clone();
                        let params = MaybeProp::derive(move || {
                            let ps = act
                                .param_map
                                .iter()
                                .map(|(k, v)| {
                                    let val = if v.starts_with("{") && v.ends_with("}") {
                                        let cv = &v[1..v.len() - 1];
                                        let col_idx = header_cells.with_untracked(|hcs| {
                                            let idx =
                                                hcs.get_position(cv).expect("没有找到对应的列");
                                            idx
                                        });
                                        let val=row_data.with_value(|row| row.as_ref().expect("没有选中行").as_array().expect("选中的行不是数组").get(col_idx)
                                            .map(|jv| json_val_to_string(jv))
                                            .unwrap_or_default());
                                        val
                                    } else if v.starts_with("@") {
                                        param_vals.with(|ps| {
                                            ps.iter()
                                                .find(|(pn, _)| pn == &v[1..])
                                                .map(|(_, pv)| pv.clone())
                                                .unwrap_or_default()
                                        })
                                    } else if v == "#COLEXP" {
                                        col_name.get()
                                    } else {
                                        v.to_string()
                                    };
                                    (k.clone(), val)
                                })
                                .collect::<Vec<_>>();
                            Some(ps)
                        });
                        view! {
                            <Report menu_id=menu_id rept_name=act.name title=title params extra_where/>
                        }
                        .into_any()
                    }
                    ActionKind::Page => {
                        let init_filters = Signal::derive(move || {
                            let filters = act
                                .param_map
                                .iter()
                                .map(|(k, v)| {
                                    let val = if v.starts_with("{") && v.ends_with("}") {
                                        let cv = &v[1..v.len() - 1];
                                        let val = row_data.with_value(|row| row.as_ref().expect("没有选中行").as_object().expect("选中的行不是对象").get(cv).map(|jv|json_val_to_string(jv)).unwrap_or_default());
                                        val
                                    } else {
                                        v.to_string()
                                    };
                                    let mut wc =
                                        WhereCause::new(k.clone(), shq_common::prelude::AndOr::And);
                                    wc.add_filter_item(
                                        shq_common::prelude::Operator::Eq,
                                        Some(val),
                                    );
                                    wc
                                })
                                .collect::<Vec<_>>();
                            filters
                        });
                        view! { <CommonPage menu_id=menu_id conf_name=act.name init_filters/> }
                            .into_any()
                    }
                };
                act_view
            })
            .collect_view();
        act_views
    };
    view! {
        <Show
            when=move || menu_item.with(|mi| mi.is_some())
        >
            <div class="flex-1 flex flex-col w-full h-full space-y-1 overflow-hidden" style=move || sub_style.get().unwrap_or_default()>
                {action_view}
            </div>
        </Show>
    }.into_any()
}

pub(super) fn get_context_sub_title(
    item: &ContextMenuItem,
    row_data: &Value,
    header_cells: &ColumnCells,
) -> Option<String> {
    let mut titles: Vec<String> = Vec::new();
    item.title_columns.iter().for_each(|tc| {
        if let Some(idx) = header_cells.get_position(tc) {
            if let Some(val) = row_data.as_array().unwrap().get(idx) {
                let val_str = json_val_to_string(val);
                if !val_str.is_empty() {
                    titles.push(val_str);
                }
            }
        }
    });
    if titles.is_empty() {
        None
    } else {
        Some(titles.join(" "))
    }
}
fn get_empl_where_cause(level: &Value, auth_filter: &AuthFilter, id: &Value) -> String {
    let level = level.as_str().expect("empl_level不是string类型");
    let id = id.as_u64().expect("empl_id不是u32类型");
    let col_name = &auth_filter.col_name;
    let exp = match auth_filter.filter_type {
        AuthFilterType::User => match level {
            "DEPT1" => format!("{col_name} in (SELECT EMID FROM DICT_USER_DEPT WHERE PDID={id})"),
            "DEPT2" => format!("{col_name} in (SELECT EMID FROM DICT_USER_DEPT WHERE DPID={id})"),
            _ => format!("{col_name} = {id}"),
        },
        AuthFilterType::Dept1 => format!("{col_name} = {id}"),
        AuthFilterType::Dept2 => match level {
            "DEPT1" => format!("{col_name} in (select DPID from DICT_DEPT where PDID={id})"),
            _ => format!("{col_name} = {id}"),
        },
    };
    exp
}
